Prettier 是一个代码风格修正工具。官网:https://prettier.io/
代码风格是所有程序员都要遇到的问题,不管是团队协作还是个人:
代码风格太主观了,根本无法让谁信服谁,也没有绝对的是非对错。有没有办法自动格式化,统一代码风格?
Prettier 是一个流行的代码格式化工具,它可以自动调整代码的样式,使其更具可读性和一致性。它支持多种编程语言,包括 JavaScript、TypeScript、HTML、CSS、SCSS、GraphQL、JSON、Markdown 等。
![[2023-07-12-080354.jpg|500]]
Prettier 的核心特点包括:
.prettierrc 文件,根据项目需求调整格式化选项。其实在很早之前已经有人开始研究哪种方式来格式化长文本是最好的(Prettier Printer),比如 Philip Wadler 在 《A prettier printer》这里给出了一些自动格式化换行的理论依据:
A good pretty printer must strike a balance between ease of use, flexibility of format, and optimality of output.
Prettier 的作者 James 在这篇论文基础上再完善了一些代码风格规则,最终成为了 Prettier 格式化代码的最终方案。比如像下面的链式调用,Prettier 输出的就比原来论文描述的要好看一些:
// 原版 "A prettier printer" 的实现
hello().then(() => {
something()
}).catch(console.error)
// Prettier 的实现
hello()
.then(() => {
something()
})
.catch(console.error)
Prettier 是如何能够做到代码的格式化?
首先,Prettier 会把代码转换成 [[002.抽象语法树|AST(抽象语法树)]],这里用到的是一个叫 Recast 的库,而 Recast 实际上也用了 Esprima 来解析 ES6。
Esprima can be used to perform lexical analysis (tokenization) or syntactic analysis (parsing) of a JavaScript program.
A simple example on Node.js REPL:
var esprima = require('esprima');
var program = 'const answer = 42';
esprima.tokenize(program);
// [
// { type: 'Keyword', value: 'const' },
// { type: 'Identifier', value: 'answer' },
// { type: 'Punctuator', value: '=' },
// { type: 'Numeric', value: '42' }
// ]
esprima.parseScript(program);
// {
// type: 'Program',
// body: [
// {
// type: 'VariableDeclaration',
// declarations: [Object],
// kind: 'const'
// }
// ],
// sourceType: 'script'
// }
^02e5fb
所以无论之前的代码怎么乱、怎么屎,Prettier 都抹掉之前的所有样式,抽成最本质的语法树。然后再用 Prettier 的代码风格规则来输出格式化后的代码。
Prettier 能够支持的格式化语言是多种多样的,并非仅仅只为 JS 服务。理论上来讲,只要把一门语言的代码抽象为语法树,然后再有对应的格式化规则,那么无论什么语言都是可以的。
Prettier 官方以及社区就提供了一些插件,通过使用插件,可以添加对新语言和文件类型的支持,让 Prettier 格式化更多种类的代码。Prettier 插件通常是单独的 npm 包,需要安装它们作为项目的依赖。插件的名称通常遵循 prettier-plugin-* 的命名规范。安装插件后,Prettier 会自动发现并使用它们。
以下是一些常见的 Prettier 插件示例:
prettier-plugin-svelte:这个插件为 Svelte 组件提供了格式化支持。安装这个插件后,可以使用 Prettier 格式化 Svelte 文件。prettier-plugin-toml:这个插件为 TOML 配置文件提供了格式化支持。安装这个插件后,可以使用 Prettier 格式化 TOML 文件。prettier-plugin-java:这个插件为 Java 语言提供了格式化支持。安装这个插件后,可以使用 Prettier 格式化 Java 文件。prettier-plugin-php:这个插件为 PHP 语言提供了格式化支持。安装这个插件后,可以使用 Prettier 格式化 PHP 文件。另外,Prettier 的官方文档里一直在强调自己是一个 Opinionated(固执己见的)的工具,这里想展开聊聊 Opinionated。
其实不仅 Prettier,我们日常使用的一些库和框架都会标明自己是 opinionated 还是 unopinionated:
![[2023-07-12-080447.jpg]]
![[Pasted image 20240321123822.png]]
按照框架/库的 opinionated 还是 unopinionated 思路来使用它们非常重要:
Prettier 属于 Opinionated 哲学,这意味着它提供的代码风格已经是最优的,不希望使用者做太多自定义的内容,而应该相信 Prettier 已经服务到位了。
新建一个项目,使用 pnpm init 进行初始化,安装 prettier:
pnpm add --save-dev --save-exact prettier
--save-exact:在 package.json 里面记录具体的版本号在 package.json 里面添加命令行脚本:
"scripts": {
// ...
"format": "prettier --write ./src"
},
之后就可以使用 pnpm format 这条命令来进行格式化代码操作。
也可以通过安装 VSCode 插件的方式来使用 Prettier。使用脚本命令和使用 VSCode 插件两者之间的差别如下:
"prettier --write .",可以一次性格式化整个项目中的所有文件。而 VSCode 插件只会在你需要时(如保存文件)格式化当前打开的文件。如果想要自定义规则,可以在项目根目录下面创建一个 .prettierrc 文件,之后使用对象的形式写入自定义规则即可:
{
"singleQuote": true,
"semi": false,
"printWidth": 120,
"useTabs": false,
"tabWidth": 2,
"bracketSpacing": true,
"trailingComma": "all",
"arrowParens": "avoid"
}
singleQuote:使用单引号而不是双引号semi:在所有代码语句的末尾添加分号printWidth:每行代码的长度限制useTabs:使用制表符缩进,而不是空格缩进tabWidth:指定一个制表符等于的空格数bracketSpacing:在对象字面量的花括号内侧使用空格作为间隔trailingComma:指定添加尾后逗号的方式
none:无尾后逗号es5:在 ES5 中有效的尾后逗号(如对象与数组等)all:尽可能添加尾后逗号(如函数的参数列表)arrowParens:箭头函数仅有一个参数时,参数是否添加括号详见 [[002.格式化规则|Prettier 格式化规则]]